package com.jianshuge.oauth;

import java.io.IOException;
import java.net.MalformedURLException;

import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.webkit.CookieSyncManager;

public class QC {

    public static String SERVER = "https://graph.qq.com/oauth2.0/";
    public static String URL_OAUTH2_ACCESS_TOKEN = "https://graph.qq.com/oauth2.0/token";
    public static String URL_OAUTH2_ACCESS_AUTHORIZE = "https://graph.qq.com/oauth2.0/authorize";

    private static String APP_KEY = "";
    private static String APP_SECRET = "";

    private static QC mWeiboInstance = null;
    private Token mAccessToken = null;

    private OAuthDialogListener mAuthDialogListener;

    private static final int DEFAULT_AUTH_ACTIVITY_CODE = 32973;

    public static final String ACCESS_TOKEN = "access_token";
    public static final String EXPIRES_IN = "expires_in";
    public static final String DEFAULT_REDIRECT_URI = "wbconnect://success";// 暂不支持
    public static final String DEFAULT_CANCEL_URI = "wbconnect://cancel";// 暂不支持

    private String mRedirectUrl;

    private QC() {
        Utility.setRequestHeader("Accept-Encoding", "gzip");
        mRedirectUrl = DEFAULT_REDIRECT_URI;
    }

    public synchronized static QC getInstance() {
        if (mWeiboInstance == null) {
            mWeiboInstance = new QC();
        }
        return mWeiboInstance;
    }

    // 设置accessToken
    public void setAccessToken(AccessToken token) {
        mAccessToken = token;
    }

    public Token getAccessToken() {
        return this.mAccessToken;
    }

    public void setupConsumerConfig(String consumer_key, String consumer_secret) {
    	QC.APP_KEY = consumer_key;
    	QC.APP_SECRET = consumer_secret;
    }

    public static String getAppKey() {
        return QC.APP_KEY;
    }

    public static String getAppSecret() {
        return QC.APP_SECRET;
    }

    public static String getSERVER() {
        return SERVER;
    }

    public static void setSERVER(String sERVER) {
        SERVER = sERVER;
    }

    public String getRedirectUrl() {
        return mRedirectUrl;
    }

    public void setRedirectUrl(String mRedirectUrl) {
        this.mRedirectUrl = mRedirectUrl;
    }

    /**
     * Requst qq open api by get or post
     * 
     * @param url
     *            Openapi request URL.
     * @param params
     *            http get or post parameters . e.g.
     *            gettimeling?max=max_id&min=min_id max and max_id is a pair of
     *            key and value for params, also the min and min_id
     * @param httpMethod
     *            http verb: e.g. "GET", "POST", "DELETE"
     * @throws IOException
     * @throws MalformedURLException
     * @throws OAuthException
     */
    public String request(Context context, String url, OAuthParameters params, String httpMethod,
            Token token) throws OAuthException {
        String rlt = Utility.openUrl(context, url, httpMethod, params, this.mAccessToken);
        return rlt;
    }

    /**
     * 获取Oauth2.0的accesstoken
     * 
     * https://graph.qq.com/oauth2.0/token?grant_type=authorization_code&client_id=[YOUR_APP_ID]&
     * client_secret=[YOUR_APP_Key]&
     * code=[The_AUTHORIZATION_CODE]&
     * state=[The_CLIENT_STATE]&
     * redirect_uri=[YOUR_REDIRECT_URI]
     * 
     * @param context
     * @param app_key
     * @param app_secret
     * @param usrname
     * @param password
     * @return
     * @throws OAuthException
     */
    public String getOauth2AccessToken(Context context, String auth_code) throws OAuthException {
        Utility.setAuthorization(new OAuth2AccessTokenHeader());
        OAuthParameters postParams = new OAuthParameters();

        postParams.add("client_id", APP_KEY);
        postParams.add("client_secret", APP_SECRET);
        postParams.add("grant_type", "authorization_code");
        postParams.add("code", auth_code);
        postParams.add("redirect_uri", mRedirectUrl);
        postParams.add("state", "12341234123");
        
        String rlt = Utility.openUrl(context, QC.URL_OAUTH2_ACCESS_TOKEN, "POST", postParams, null);

        return rlt;
    }

    private boolean startSingleSignOn(Activity activity, String applicationId,
            String[] permissions, int activityCode) {
        return false;
    }

    private void startDialogAuth(Activity activity, String[] permissions) {
        OAuthParameters params = new OAuthParameters();
        if (permissions.length > 0) {
            params.add("scope", TextUtils.join(",", permissions));
        }
        CookieSyncManager.createInstance(activity);
        dialog(activity, params, new OAuthDialogListener() {

            public void onComplete(Bundle values) {
                // ensure any cookies set by the dialog are saved
                CookieSyncManager.getInstance().sync();
                
                if (null == mAccessToken) {
                    mAccessToken = new Token();
                }
                
                mAccessToken.setToken(values.getString(ACCESS_TOKEN));
                mAccessToken.setExpiresIn(values.getString(EXPIRES_IN));
                if (isSessionValid()) {
                    Log.d("Weibo-authorize", "Login Success! access_token=" + mAccessToken.getToken() + " expires=" + mAccessToken.getExpiresIn());
                    mAuthDialogListener.onComplete(values);
                } else {
                    Log.d("Weibo-authorize", "Failed to receive access token");
                    mAuthDialogListener.onAuthException(new OAuthException("Failed to receive access token."));
                }
            }

            public void onError(OAuthDialogError error) {
                Log.d("Weibo-authorize", "Login failed: " + error);
                mAuthDialogListener.onError(error);
            }

            public void onAuthException(OAuthException error) {
                Log.d("Weibo-authorize", "Login failed: " + error);
                mAuthDialogListener.onAuthException(error);
            }

            public void onCancel() {
                Log.d("Weibo-authorize", "Login canceled");
                mAuthDialogListener.onCancel();
            }
        });
    }

    /**
     * User-Agent Flow
     * 
     * @param activity
     * 
     * @param listener
     *            授权结果监听器
     */
    public void authorize(Activity activity, final OAuthDialogListener listener) {
        authorize(activity, new String[] {}, DEFAULT_AUTH_ACTIVITY_CODE, listener);
    }

    private void authorize(Activity activity, String[] permissions, final OAuthDialogListener listener) {
        authorize(activity, permissions, DEFAULT_AUTH_ACTIVITY_CODE, listener);
    }

    private void authorize(Activity activity, String[] permissions, int activityCode,
            final OAuthDialogListener listener) {
        Utility.setAuthorization(new OAuth2AccessTokenHeader());

        boolean singleSignOnStarted = false;
        mAuthDialogListener = listener;

        // Prefer single sign-on, where available.
        if (activityCode >= 0) {
            singleSignOnStarted = startSingleSignOn(activity, APP_KEY, permissions, activityCode);
        }
        // Otherwise fall back to traditional dialog.
        if (!singleSignOnStarted) {
            startDialogAuth(activity, permissions);
        }

    }

    private void authorizeCallBack(int requestCode, int resultCode, Intent data) {

    }

    public void dialog(Context context, OAuthParameters parameters,
            							final OAuthDialogListener listener) {
    	
        parameters.add("client_id", APP_KEY);
        parameters.add("response_type", "code");
        parameters.add("redirect_uri", mRedirectUrl);
        parameters.add("scope", "get_user_info,add_share,list_album,add_album,upload_pic,add_topic,add_one_blog,add_weibo");
        parameters.add("display", "mobile");

        if (isSessionValid()) {
            parameters.add(ACCESS_TOKEN, mAccessToken.getToken());
        }
        String url = URL_OAUTH2_ACCESS_AUTHORIZE + "?" + Utility.encodeUrl(parameters);
        System.out.println( url );
        if (context.checkCallingOrSelfPermission(Manifest.permission.INTERNET) != PackageManager.PERMISSION_GRANTED) {
            Utility.showAlert(context, "Error",
                    "Application requires permission to access the Internet");
        } else {
            new QCDialog(this, context, url, listener).show();
        }
    }

    public boolean isSessionValid() {
    	

        if (mAccessToken != null) {
        	System.out.println("Token is " + mAccessToken.getToken());
        	System.out.println("ExpiresIn is " + mAccessToken.getExpiresIn());
        	System.out.println("currentTime is " + System.currentTimeMillis());


            return ( 
            		!TextUtils.isEmpty(mAccessToken.getToken()) && 
            		(mAccessToken.getExpiresIn() == 0 || (System.currentTimeMillis() < mAccessToken.getExpiresIn()) )
            );
        }
        return false;
    }
    
    /*-------------------------New Code----------------------------*/
    /**
     * 分享到QQ空间
     */
    public boolean shareToQZone(Activity activity, String accessToken, String tokenSecret, String content) throws OAuthException {
    	Utility.setAuthorization(new OAuth2AccessTokenHeader());
    	OAuthParameters bundle = new OAuthParameters();
        bundle.add("source", APP_KEY);
        bundle.add("status", content);
        String url = SERVER + "statuses/update.json";
        if(mAccessToken == null){
        	mAccessToken = new AccessToken(accessToken, tokenSecret);
        }
        request(activity, url, bundle, Utility.HTTPMETHOD_POST, mAccessToken);
        return true;
    }
    /*------------------------------------------------------------*/
    
	/**
	 * 分享到QQ空间 ,带图片
	 */
	public boolean shareToweiboWithFile(Activity context, String accessToken,
			String tokenSecret, String content, String fileUrl) throws OAuthException {
		Utility.setAuthorization(new OAuth2AccessTokenHeader());
		OAuthParameters bundle = new OAuthParameters();
		bundle.add("source", APP_KEY);
		bundle.add("status", content);
        if(fileUrl!=null){
        	bundle.add("pic", fileUrl);
        }		
		String url = SERVER + "statuses/upload.json";
		if (mAccessToken == null) {
			mAccessToken = new AccessToken(accessToken, tokenSecret);
		}
		request(context, url, bundle, Utility.HTTPMETHOD_POST, mAccessToken);
		return true;
	}
}
